﻿using System;
using System.Reflection;

namespace Creventive.Wpf.ShellFactory.Modules
{
    /// <summary>
    ///   Represents information about a module.
    /// </summary>
    public abstract class ModuleInfo
    {
        private readonly AssemblyName assemblyName;
        private bool isLoaded;

        /// <summary>
        ///   Initializes a new instance of the <see cref = "ModuleInfo" /> class.
        /// </summary>
        /// <param name = "assemblyName">Name of the assembly.</param>
        protected ModuleInfo(AssemblyName assemblyName)
        {
            if (assemblyName == null)
                throw new ArgumentNullException("assemblyName");
            this.assemblyName = assemblyName;
        }

        /// <summary>
        ///   Occurs when the module has been loaded.
        /// </summary>
        public event EventHandler Loaded;

        /// <summary>
        ///   Gets the application module object. This property may be null.
        /// </summary>
        /// <value>The application module.</value>
        public abstract ApplicationModule ApplicationModule { get; }

        /// <summary>
        ///   Gets the name of the assembly that contains this module.
        /// </summary>
        /// <value>The name of the assembly.</value>
        public AssemblyName AssemblyName
        {
            get { return this.assemblyName; }
        }

        /// <summary>
        ///   Gets a value indicating whether this module has been loaded.
        /// </summary>
        /// <value><c>true</c> if this instance is loaded; otherwise, <c>false</c>.</value>
        public bool IsLoaded
        {
            get { return this.isLoaded; }
        }

        /// <summary>
        ///   Gets the type of the module.
        /// </summary>
        /// <value>The type of the module.</value>
        public abstract ModuleType ModuleType { get; }

        /// <summary>
        ///   Called right before the module has been loaded. It is the responsibility of this method to call the OnLoaded method when done.
        /// </summary>
        /// <param name = "applicationModule">The application module.</param>
        protected internal abstract void OnBeforeLoaded(ApplicationModule applicationModule);

        /// <summary>
        ///   Called when the module has been loaded.
        /// </summary>
        protected virtual void OnLoaded()
        {
            this.isLoaded = true;
            var handler = this.Loaded;
            if (handler != null)
                handler.Invoke(this, EventArgs.Empty);
        }
    }
}